package com.koron.css2.newProjectCenter.impl;

import cn.hutool.core.bean.BeanUtil;
import com.koron.css2.ImportExcelInterface;
import com.koron.css2.baseConfig.bean.PrefStrategyBean;
import com.koron.css2.baseConfig.bean.WaterTypeBean;
import com.koron.css2.baseConfig.mapper.BusinessAreaMapper;
import com.koron.css2.baseConfig.mapper.PrefStrategyMapper;
import com.koron.css2.baseConfig.mapper.UserTypeMapper;
import com.koron.css2.baseConfig.mapper.WaterTypeMapper;
import com.koron.css2.clientCenter.bean.AccountInfoBean;
import com.koron.css2.clientCenter.bean.CtmInfoBean;
import com.koron.css2.clientCenter.bean.UserBean;
import com.koron.css2.clientCenter.mapper.AccountInfoMapper;
import com.koron.css2.clientCenter.mapper.CtmInfoMapper;
import com.koron.css2.clientCenter.mapper.UserInfoMapper;
import com.koron.css2.clientCenter.queryBean.AccountInfoQueryBean;
import com.koron.css2.clientCenter.queryBean.CtmInfoQueryBean;
import com.koron.css2.clientCenter.queryBean.UserInfoQueryBean;
import com.koron.css2.common.dto.HeaderInfoDto;
import com.koron.css2.meterService.dto.MsInfoDto;
import com.koron.css2.meterService.mapper.MsInfoMapper;
import com.koron.css2.newProjectCenter.bean.PjInfoBean;
import com.koron.css2.newProjectCenter.bean.PjMeter;
import com.koron.css2.newProjectCenter.bean.query.PjInfoQueryBean;
import com.koron.css2.newProjectCenter.bean.query.PjMeterQuery;
import com.koron.css2.newProjectCenter.exception.UserNoException;
import com.koron.css2.newProjectCenter.mapper.PjInfoMapper;
import com.koron.css2.newProjectCenter.mapper.PjMeterMapper;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.util.Constant;
import com.koron.util.Tools;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.stream.Collectors;

public class PjMeterRegisterAccountImport implements ImportExcelInterface {

    /**
     * 立户节点批量导入最大条数
     */
    private static final int MAX_COUNT = 3000;

    @Override
    public MessageBean<?> importExel(SessionFactory factory, UserInfoBean userInfo, RequestBean req,
                                     List<Map<String, String>> data, MultipartFile file) {
        try {
            // 限制最大导入条数
            if (data.size() > MAX_COUNT){
                return MessageBean.create(Constant.MESSAGE_INT_FAIL, "已超过最大的数据导入条数：" + MAX_COUNT + "，导入失败", null);
            }
            List<PjMeter> newPjMeterList = new ArrayList<>();
            List<CtmInfoBean> ctmInfoBeanList = new ArrayList<>();
            List<AccountInfoBean> accountInfoBeanList = new ArrayList<>();
            List<UserBean> userBeanList = new ArrayList<>();
            Map<String, Object> paramMap = BeanUtil.beanToMap(req.getData());
            PjInfoMapper pjInfoMapper = factory.getMapper(PjInfoMapper.class);
            PjMeterMapper pjMeterMapper = factory.getMapper(PjMeterMapper.class);
            CtmInfoMapper ctmInfoMapper = factory.getMapper(CtmInfoMapper.class);
            AccountInfoMapper accountInfoMapper = factory.getMapper(AccountInfoMapper.class);
            UserInfoMapper userInfoMapper = factory.getMapper(UserInfoMapper.class);
            MsInfoMapper msInfoMapper = factory.getMapper(MsInfoMapper.class);
            UserTypeMapper userTypeMapper = factory.getMapper(UserTypeMapper.class);

            // 对billNo以及对应的工程报装进行校验
            String billNo = data.get(0).get("billNo");
            if (StringUtils.isEmpty(billNo)) {
                return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入工程编号", null);
            }
            PjInfoQueryBean pjInfoQueryBean = new PjInfoQueryBean();
            pjInfoQueryBean.setBillNo(billNo);
            PjInfoBean pjInfoBean = pjInfoMapper.getSingle(pjInfoQueryBean);
            if (pjInfoBean == null) {
                return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的工程编号", null);
            }
            String consultId = pjInfoBean.getId();

            // 1. 循环获取数据
            for (Map<String, String> map : data) {
                PjMeter pjMeter = new PjMeter();
                MsInfoDto msInfoDto = new MsInfoDto();

                // 2. 立户阶段-客户信息
                CtmInfoBean ctmInfoBean = new CtmInfoBean();
                // 2.1 certNo
                String certNo = map.get("certNo");
                if (StringUtils.isEmpty(certNo)) {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入客户证件号码", null);
                }
                ctmInfoBean.setCertNo(certNo);
                // 2.2 ctmName
                String ctmName = map.get("ctmName");
                if (StringUtils.isEmpty(ctmName)) {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入客户名称", null);
                }
                ctmInfoBean.setCtmName(ctmName);
                // 2.4 clientAddrDetail
                String clientAddrDetail = map.get("clientAddrDetail");
                ctmInfoBean.setClientAddrDetail(clientAddrDetail);
                // 2.5 ctmType
                String ctmTypeName = map.get("ctmType");
                if (StringUtils.isNotEmpty(ctmTypeName)) {
                    String ctmType = Tools.getDicValueByCodeAndName(factory, "CTT", ctmTypeName);
                    if (StringUtils.isEmpty(ctmType)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的客户类型", null);
                    }
                    ctmInfoBean.setCtmType(ctmType);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入客户类型", null);
                }
                // 2.6 certType
                String certTypeName = map.get("certType");
                if (StringUtils.isNotEmpty(certTypeName)) {
                    String certType = Tools.getDicValueByCodeAndName(factory, "IDT", certTypeName);
                    if (StringUtils.isEmpty(certType)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的证件类型", null);
                    }
                    ctmInfoBean.setCertType(certType);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入证件类型", null);
                }
                // 2.7 creditLevel
                String creditLevelName = map.get("creditLevel");
                if (StringUtils.isNotEmpty(creditLevelName)) {
                    String creditLevel = Tools.getDicValueByCodeAndName(factory, "CDL", creditLevelName);
                    if (StringUtils.isEmpty(creditLevel)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的信用等级", null);
                    }
                    ctmInfoBean.setCreditLevel(creditLevel);
                }
                // 2.8 linkTel
                ctmInfoBean.setLinkTel(map.get("linkTel"));
                // 2.9 mobile
                ctmInfoBean.setMobile(map.get("mobile"));
                // 2.10 faxNumber
                ctmInfoBean.setFaxNumber(map.get("faxNumber"));
                // 2.11 存储客户信息，后续批量添加
                ctmInfoBeanList.add(ctmInfoBean);

                // 3. 立户阶段-账户信息
                AccountInfoBean accountInfoBean = new AccountInfoBean();
                // 3.1 payWay
                String payWayName = map.get("payWay");
                if (StringUtils.isNotEmpty(payWayName)) {
                    String payWay = Tools.getDicValueByCodeAndName(factory, "BPW", payWayName);
                    if (StringUtils.isEmpty(payWay)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的缴费方式", null);
                    }
                    accountInfoBean.setPayWay(payWay);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入缴费方式", null);
                }
                // 3.2 accountType
                String accountTypeName = map.get("accountType");
                if (StringUtils.isNotEmpty(accountTypeName)) {
                    String accountType = Tools.getDicValueByCodeAndName(factory, "ACT", accountTypeName);
                    if (StringUtils.isEmpty(accountType)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的账户类型", null);
                    }
                    accountInfoBean.setAccountType(accountType);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入账户类型", null);
                }
                // 3.3 deliverWay
                String deliverWayName = map.get("deliverWay");
                if (StringUtils.isNotEmpty(deliverWayName)) {
                    String deliverWay = Tools.getDicValueByCodeAndName(factory, "SDW", deliverWayName);
                    if (StringUtils.isEmpty(deliverWay)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的投递方式", null);
                    }
                    accountInfoBean.setDeliverWay(deliverWay);
                }
                // 3.4 deliverAddr
                accountInfoBean.setDeliverAddr(map.get("deliverAddr"));
                // 3.5 emailAddr
                accountInfoBean.setEmailAddr(map.get("emailAddr"));
                // 3.6 invoiceTitle
                accountInfoBean.setInvoiceTitle(map.get("invoiceTitle"));
                // 3.7 invoiceTax
                accountInfoBean.setInvoiceTax(map.get("invoiceTax"));
                // 3.8 invoiceAddr
                accountInfoBean.setInvoiceAddr(map.get("invoiceAddr"));
                // 3.9 invoiceLink
                accountInfoBean.setInvoiceLink(map.get("invoiceLink"));
                // 3.10 invoiceBank
                accountInfoBean.setInvoiceBank(map.get("invoiceBank"));
                // 3.11 invoiceAccount
                accountInfoBean.setInvoiceAccount(map.get("invoiceAccount"));
                // 3.12 vatFlag
                String vatFlagName = map.get("vatFlag");
                if (StringUtils.isNotEmpty(vatFlagName)) {
                    if (vatFlagName.equals("是")) {
                        accountInfoBean.setVatFlag("1");
                    } else if (vatFlagName.equals("否")) {
                        accountInfoBean.setVatFlag("0");
                    } else {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的增值税标记", null);
                    }
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入增值税标记", null);
                }
                // 3.13 preInvoicing
                String preInvoicingName = map.get("preInvoicing");
                if (StringUtils.isNotEmpty(preInvoicingName)) {
                    if (preInvoicingName.equals("是")) {
                        accountInfoBean.setPreInvoicing(1);
                    } else if (preInvoicingName.equals("否")) {
                        accountInfoBean.setPreInvoicing(0);
                    } else {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的预开票标记", null);
                    }
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入预开票标记", null);
                }
                // 3.14 mergeInvoicing
                String mergeInvoicingName = map.get("mergeInvoicing");
                if (StringUtils.isNotEmpty(mergeInvoicingName)) {
                    if (mergeInvoicingName.equals("是")) {
                        accountInfoBean.setMergeInvoicing(1);
                    } else if (mergeInvoicingName.equals("否")) {
                        accountInfoBean.setMergeInvoicing(0);
                    } else {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的合并开票标记", null);
                    }
                }
                // 3.15 存储账户信息，后续批量添加
                accountInfoBeanList.add(accountInfoBean);

                // 4. 动态用户信息
                UserBean userBean = new UserBean();
                // 4.1 contractNo
                userBean.setContractNo(map.get("contractNo"));
                // 4.2 contractDate
                userBean.setContractDate(map.get("contractDate"));
                // 4.3 useTimeLimit
                userBean.setUseTimeLimit(map.get("useTimeLimit"));
                // 4.4 businessArea
                String businessAreaName = map.get("businessArea");
                if (StringUtils.isNotEmpty(businessAreaName)) {
                    BusinessAreaMapper businessAreaMapper = factory.getMapper(BusinessAreaMapper.class);
                    String businessAreaId = businessAreaMapper.getIdByAreaName(businessAreaName);
                    if (StringUtils.isEmpty(businessAreaId)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的营业区域", null);
                    }
                    userBean.setBusinessArea(businessAreaId);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入营业区域", null);
                }
                // 4.5 stopWaterLinkMan
                userBean.setStopWaterLinkMan(map.get("stopWaterLinkMan"));
                // 4.6 stopWaterLinkMobile
                userBean.setStopWaterLinkMobile(map.get("stopWaterLinkMobile"));
                // 4.7 userGroupNo
                userBean.setUserGroupNo(map.get("userGroupNo"));
                // 4.8 comments
                userBean.setComments(map.get("comments"));
                // 册本号
                userBean.setBookNo(Objects.toString(map.get("bookNo"), ""));
                // 抄表周期
                userBean.setMeterReadingCycle(Objects.toString(map.get("meterReadingCycle"), ""));
                // 下次抄表月
                if (StringUtils.isNotEmpty(map.get("nextMonthid"))){
                    userBean.setNextMonthid(Integer.parseInt(map.get("nextMonthid")));
                }
                // 4.9 meterNo
                String meterNo = map.get("meterNo");
                if (StringUtils.isEmpty(meterNo)) {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入水表编号", null);
                }
                // 4.9.1 msInfoId
                userBean.setMeterNo(meterNo);
                String msInfoId = msInfoMapper.getIdByMeterNo(meterNo);
                if (StringUtils.isEmpty(msInfoId)) {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的水表编号", null);
                }
                pjMeter.setMsInfoId(msInfoId);
                // 4.11 clientContractAddrDetail
                String clientContractAddrDetail = map.get("clientContractAddrDetail");
                userBean.setClientContractAddrDetail(clientContractAddrDetail);
                // 4.12 meterBjms
                String meterBjmsName = map.get("meterBjms");
                if (StringUtils.isNotEmpty(meterBjmsName)) {
                    String meterBjms = Tools.getDicValueByCodeAndName(factory, "BJMS", meterBjmsName);
                    if (StringUtils.isEmpty(meterBjms)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的表井模式", null);
                    }
                    userBean.setMeterBjms(meterBjms);
                }
                // 4.13 meterUse
                String meterUseName = map.get("meterUse");
                if (StringUtils.isNotEmpty(meterUseName)) {
                    String meterUse = Tools.getDicValueByCodeAndName(factory, "CMC", meterUseName);
                    if (StringUtils.isEmpty(meterUse)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的水表用途", null);
                    }
                    userBean.setMeterUse(meterUse);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入水表用途", null);
                }
                // 4.14 useWaterObject
                String useWaterObjectName = map.get("useWaterObject");
                if (StringUtils.isNotEmpty(useWaterObjectName)) {
                    String useWaterObject = Tools.getDicValueByCodeAndName(factory, "UWS", useWaterObjectName);
                    if (StringUtils.isEmpty(useWaterObject)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的用水对象", null);
                    }
                    userBean.setUseWaterObject(useWaterObject);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入用水对象", null);
                }
                // 4.15 setupMeterDate
                String setupMeterDate = map.get("setupMeterDate");
                if (StringUtils.isEmpty(setupMeterDate)) {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入装表日期", null);
                }
                userBean.setSetupMeterDate(setupMeterDate);
                // 4.16 miicno
                userBean.setMiicno(map.get("miicno"));
                // 4.17 miljfje
                userBean.setMiljfje(map.get("miljfje"));
                // 4.18 quotaWater
                if (StringUtils.isNotEmpty(map.get("quotaWater"))) {
                    userBean.setQuotaWater(Integer.parseInt(map.get("quotaWater")));
                }
                // 4.19 concentratorNo
                userBean.setConcentratorNo(map.get("concentratorNo"));
                // 4.20 meterSite
                userBean.setMeterSite(map.get("meterSite"));
                // 4.21 meterBjxs
                String meterBjxsName = map.get("meterBjxs");
                if (StringUtils.isNotEmpty(meterBjxsName)) {
                    String meterBjxs = Tools.getDicValueByCodeAndName(factory, "BJXS", meterBjxsName);
                    if (StringUtils.isEmpty(meterBjxs)) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的表井形式", null);
                    }
                    userBean.setMeterBjxs(meterBjxs);
                }
                // 4.22 realEstateNo
                userBean.setRealEstateNo(map.get("realEstateNo"));
                // 4.23 bankCode
                userBean.setBankCode(map.get("bankCode"));
                // 4.24 bankSubAccount
                userBean.setBankSubAccount(map.get("bankSubAccount"));

                // 5. 立户阶段-用户信息：价格信息
                // 5.1 useWaterType
                String useWaterTypeName = map.get("useWaterType");
                if (StringUtils.isNotEmpty(useWaterTypeName)) {
                    WaterTypeMapper waterTypeMapper = factory.getMapper(WaterTypeMapper.class);
                    WaterTypeBean waterTypeBean = waterTypeMapper.findWaterTypeByName(useWaterTypeName);
                    if (waterTypeBean == null) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的用水类型", null);
                    }
                    userBean.setUseWaterType(waterTypeBean.getId());
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入用水类型", null);
                }
                // 5.2 prefStrategyId
                String prefStrategyName = map.get("prefStrategyId");
                if (StringUtils.isNotEmpty(prefStrategyName)) {
                    PrefStrategyMapper prefStrategyMapper = factory.getMapper(PrefStrategyMapper.class);
                    PrefStrategyBean prefStrategyBean = prefStrategyMapper.selectPrefStrategyByname(prefStrategyName);
                    if (prefStrategyBean == null) {
                        return MessageBean.create(Constant.MESSAGE_INT_FAIL, "请输入正确的优惠策略", null);
                    }
                    userBean.setPrefStrategyId(prefStrategyBean.getId());
                }
                // 5.3 prefCertNo
                userBean.setPrefCertNo(map.get("prefCertNo"));
                // 5.4 prefBeginDate
                userBean.setPrefBeginDate(map.get("prefBeginDate"));
                // 5.5 prefEndDate
                userBean.setPrefEndDate(map.get("prefEndDate"));
                // 获取用户编号
                userBean.setUserNo(map.get("userNo"));
                //用户特殊类型
                String userType = userTypeMapper.getUserIdByTypeName(map.get("userType"));
                userBean.setUserType(userType);


                // 6. 存储用户信息，后续批量添加
                userBeanList.add(userBean);

                pjMeter.setUserInfo(userBean);
                pjMeter.setCtmInfo(ctmInfoBean);
                pjMeter.setAccountInfo(accountInfoBean);
                pjMeter.setMsInfo(msInfoDto);
                pjMeter.setCreateInfo(userInfo);
                pjMeter.setConsultId(consultId);
                newPjMeterList.add(pjMeter);
            }
            // 表身码不能重复
            List<String> factoryNoList = userBeanList.stream().map(UserBean::getMeterNo).collect(Collectors.toList());
            Set<String> factoryNoSet = userBeanList.stream().map(UserBean::getMeterNo).collect(Collectors.toSet());
            if (factoryNoSet.size() != factoryNoList.size()) {
                return MessageBean.create(Constant.MESSAGE_INT_FAIL,"水表编码不能重复",null);
            }
            // 7.先查出原有的pjMeter
            PjMeterQuery pjMeterQuery = new PjMeterQuery();
            pjMeterQuery.setConsultId(consultId);
            List<PjMeter> oldPjMeterList = pjMeterMapper.getList(pjMeterQuery);
            // 7.1 查出所有的临时用户id
            List<String> userTempIdList = oldPjMeterList.stream().map(PjMeter::getUserInfoTempId).collect(Collectors.toList());
            // 7.2 查出所有的临时客户id
            List<String> ctmTempIdList = oldPjMeterList.stream().map(PjMeter::getUserCtmTempId).collect(Collectors.toList());
            // 7.3 查出所有的临时账户id
            List<String> accountTempIdList = oldPjMeterList.stream().map(PjMeter::getUserAccountTempId).collect(Collectors.toList());
            // 8.1 删除所有pjMeter
            pjMeterMapper.delete(pjMeterQuery);
            // 8.2 删除所有的临时用户
            if (userTempIdList != null && userTempIdList.size() >0) {
                UserInfoQueryBean userInfoQueryBean = new UserInfoQueryBean();
                userInfoQueryBean.setIdList(userTempIdList);
                userInfoMapper.batchDelete(userInfoQueryBean, UserBean.USERTEMP);
            }

            Integer singleCustomerFlag = Integer.valueOf(String.valueOf(paramMap.get("singleCustomerFlag")));

            // 排序有用户编号的在前面
            newPjMeterList = sortListByUserNo(newPjMeterList);
            PjSave pjSave = new PjSave();
            // 9. 单客户的情况: 不更新客户/账户信息；新增用户信息；新增水表信息
            if (singleCustomerFlag == 1) {
                // 9.1 查询原有的客户
                CtmInfoBean oldCtm = ctmInfoMapper.getCtmInfoById(pjInfoBean.getUserCtmTempId(), CtmInfoBean.CTMTEMP);
                // 9.2 查询原有的账户
                AccountInfoBean oldAccount = accountInfoMapper.getAccountInfoById(pjInfoBean.getUserAccountTempId(), AccountInfoBean.ACCOUNTTEMP);
                // 9.3 更新第一个水表；并将第一个水表的客户编号，账户编号和用户编号保持一致
                // 9.3.1 保存第一个临时用户，并返回userNo
                PjMeter firstMeter = newPjMeterList.get(0);
                String firstUserNo = pjSave.saveMeterUserInfoTemp(factory, userInfo, firstMeter, oldCtm, oldAccount, firstMeter.getMsInfo());
                // 9.3.2 同步客户编号和账户编号
                String ctmNo = Tools.getSameCtmNo(firstUserNo);
                String accountNo = Tools.getSameAccountNo(firstUserNo);
                // 9.3.3 更新临时客户和临时账户
                oldCtm.setCtmNo(ctmNo);
                oldAccount.setAccountNo(accountNo);
                ctmInfoMapper.ctmInfoUpdate(oldCtm, CtmInfoBean.CTMTEMP);
                accountInfoMapper.accountInfoUpdate(oldAccount, AccountInfoBean.ACCOUNTTEMP);
                // 9.3.4 将新的客户编号和账户编号回填到临时用户中
                UserBean firstUserTemp = userInfoMapper.getUserInfoByUserNo(firstUserNo, UserBean.USERTEMP);
                firstUserTemp.setAccountNo(accountNo);
                firstUserTemp.setCtmNo(ctmNo);
                userInfoMapper.userInfoUpdate(firstUserTemp, UserBean.USERTEMP);
                // 9.3.5 将客户id和账户id回填到水表中
                firstMeter.setUserCtmTempId(oldCtm.getId());
                firstMeter.setUserAccountTempId(oldAccount.getId());
                // 9.4 更新剩下的水表
                for (int i = 1; i < newPjMeterList.size(); i++) {
                    PjMeter pjMeter = newPjMeterList.get(i);
                    pjSave.saveMeterUserInfoTemp(factory, userInfo, pjMeter, oldCtm, oldAccount, pjMeter.getMsInfo());
                    pjMeter.setUserCtmTempId(oldCtm.getId());
                    pjMeter.setUserAccountTempId(oldAccount.getId());
                }
                // 9.5. 批量新增pjMeter
                pjMeterMapper.batchInsert(newPjMeterList);
            }
            // 10. 多客户情况：删除原有客户，账户信息；新增用户信息
            if (singleCustomerFlag == 0) {
                // 10.1 删除所有的临时客户
                CtmInfoQueryBean ctmInfoQueryBean = new CtmInfoQueryBean();
                ctmInfoQueryBean.setIdList(ctmTempIdList);
                ctmInfoMapper.batchDelete(ctmInfoQueryBean, CtmInfoBean.CTMTEMP);
                // 10.2 删除所有的临时账户
                AccountInfoQueryBean accountInfoQueryBean = new AccountInfoQueryBean();
                accountInfoQueryBean.setIdList(accountTempIdList);
                accountInfoMapper.batchDelete(accountInfoQueryBean, AccountInfoBean.ACCOUNTTEMP);


                for (int i = 0; i < newPjMeterList.size(); i++) {
                    PjMeter pjMeter = newPjMeterList.get(i);
                    // 10.3 新增客户
                    CtmInfoBean ctmInfoBean = pjMeter.getCtmInfo();
                    ctmInfoBean.setCreateInfo(userInfo);
                    ctmInfoMapper.ctmInfoAdd(ctmInfoBean, CtmInfoBean.CTMTEMP);
                    // 10.4 新增账户
                    AccountInfoBean accountInfoBean = pjMeter.getAccountInfo();
                    accountInfoBean.setCreateInfo(userInfo);
                    accountInfoMapper.accountInfoAdd(accountInfoBean, AccountInfoBean.ACCOUNTTEMP);
                    // 10.5 保存用户
                    String userNo = pjSave.saveMeterUserInfoTemp(factory, userInfo, pjMeter, ctmInfoBean, accountInfoBean, pjMeter.getMsInfo());
                    // 10.6 同步客户编号和账户编号
                    String ctmNo = Tools.getSameCtmNo(userNo);
                    String accountNo = Tools.getSameAccountNo(userNo);
                    // 10.7 更新临时客户和临时账户
                    ctmInfoBean.setCtmNo(ctmNo);
                    accountInfoBean.setAccountNo(accountNo);
                    ctmInfoMapper.ctmInfoUpdate(ctmInfoBean, CtmInfoBean.CTMTEMP);
                    accountInfoMapper.accountInfoUpdate(accountInfoBean, AccountInfoBean.ACCOUNTTEMP);
                    // 10.8 将新的客户编号和账户编号回填到临时用户中
                    UserBean userBean = userInfoMapper.getUserInfoByUserNo(userNo, UserBean.USERTEMP);
                    userBean.setAccountNo(accountNo);
                    userBean.setCtmNo(ctmNo);
                    userInfoMapper.userInfoUpdate(userBean, UserBean.USERTEMP);
                    // 10.9 将客户id和账户id回填到水表中
                    pjMeter.setUserCtmTempId(ctmInfoBean.getId());
                    pjMeter.setUserAccountTempId(accountInfoBean.getId());
                    //更新报装主表
                    pjInfoBean.setUserCtmTempId(ctmInfoBean.getId());
                    pjInfoBean.setUserAccountTempId(accountInfoBean.getId());
                    pjInfoMapper.updateTempId(pjInfoBean);

                }
                // 10.10 批量新增pjMeter
                pjMeterMapper.batchInsert(newPjMeterList);
            }

            // 11. 返回数据
            MessageBean<List> msg = MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "工程报装-水表信息导入成功", List.class);
            msg.setData(newPjMeterList);

            return msg;
        }catch (UserNoException e){
            return MessageBean.create(Constant.MESSAGE_INT_FAIL, e.getMessage(), null);
        }
        catch (Exception e) {
            factory.close(false);
            logger.error("工程报装-水表导入失败", e);
            return MessageBean.create(Constant.MESSAGE_INT_FAIL, "工程报装-水表导入失败", null);
        }
    }

    /**
     * 根据是否具有用户编号排序 有编号的在前面
     */
    private List<PjMeter> sortListByUserNo(List<PjMeter> newPjMeterList) {
        List<PjMeter> first = newPjMeterList.stream().filter(item -> StringUtils.isNotBlank(item.getUserInfo().getUserNo())).collect(Collectors.toList());
        List<PjMeter> end = newPjMeterList.stream().filter(item -> StringUtils.isBlank(item.getUserInfo().getUserNo())).collect(Collectors.toList());
        first.addAll(end);
        return first;
    }

    @Override
    public List<HeaderInfoDto> getHeaderInfo(UserInfoBean userInfo) {
        List<HeaderInfoDto> headerInfos = new ArrayList<HeaderInfoDto>();
        headerInfos.add(new HeaderInfoDto("工程编号", false, "billNo"));

        // 1. 立户-客户信息
        headerInfos.add(new HeaderInfoDto("客户证件号码", false, "certNo"));
        headerInfos.add(new HeaderInfoDto("客户名称", false, "ctmName"));
        headerInfos.add(new HeaderInfoDto("客户单元地址", false, "clientAddrDetail"));
        headerInfos.add(new HeaderInfoDto("客户类型", false, "ctmType"));
        headerInfos.add(new HeaderInfoDto("证件类型", false, "certType"));
        headerInfos.add(new HeaderInfoDto("信用等级", false, "creditLevel"));
        headerInfos.add(new HeaderInfoDto("固定电话", false, "linkTel"));
        headerInfos.add(new HeaderInfoDto("手机号码", false, "mobile"));
        headerInfos.add(new HeaderInfoDto("传真号码", false, "faxNumber"));

        // 2. 立户-账户信息
        headerInfos.add(new HeaderInfoDto("缴费方式", false, "payWay"));
        headerInfos.add(new HeaderInfoDto("账户类型", false, "accountType"));
        headerInfos.add(new HeaderInfoDto("投递方式", false, "deliverWay"));
        headerInfos.add(new HeaderInfoDto("投递地址", false, "deliverAddr"));
        headerInfos.add(new HeaderInfoDto("电子邮件", false, "emailAddr"));
        headerInfos.add(new HeaderInfoDto("单位名称", false, "invoiceTitle"));
        headerInfos.add(new HeaderInfoDto("纳税人识别号", false, "invoiceTax"));
        headerInfos.add(new HeaderInfoDto("联系地址", false, "invoiceAddr"));
        headerInfos.add(new HeaderInfoDto("座机号码", false, "invoiceLink"));
        headerInfos.add(new HeaderInfoDto("开户银行", false, "invoiceBank"));
        headerInfos.add(new HeaderInfoDto("银行账户", false, "invoiceAccount"));
        headerInfos.add(new HeaderInfoDto("增值税标记", false, "vatFlag"));
        headerInfos.add(new HeaderInfoDto("预开票标记", false, "preInvoicing"));
        headerInfos.add(new HeaderInfoDto("合并开票标记", false, "mergeInvoicing"));

        // 3. 立户-用户信息：目前是写死的。不知道怎么动态生成
        headerInfos.add(new HeaderInfoDto("合同编号", false, "contractNo"));
        headerInfos.add(new HeaderInfoDto("签订日期", false, "contractDate"));
        headerInfos.add(new HeaderInfoDto("用水期限", false, "useTimeLimit"));
        headerInfos.add(new HeaderInfoDto("营业区域", false, "businessArea"));
        headerInfos.add(new HeaderInfoDto("通知人", false, "stopWaterLinkMan"));
        headerInfos.add(new HeaderInfoDto("通知人手机", false, "stopWaterLinkMobile"));
        headerInfos.add(new HeaderInfoDto("用户组编号", false, "userGroupNo"));
        headerInfos.add(new HeaderInfoDto("备注", false, "comments"));
        headerInfos.add(new HeaderInfoDto("水表编号", false, "meterNo"));
        headerInfos.add(new HeaderInfoDto("装表单元地址", false, "clientContractAddrDetail"));
        headerInfos.add(new HeaderInfoDto("表井模式", false, "meterBjms"));
        headerInfos.add(new HeaderInfoDto("水表用途", false, "meterUse"));
        headerInfos.add(new HeaderInfoDto("用水对象", false, "useWaterObject"));
        headerInfos.add(new HeaderInfoDto("装表日期", false, "setupMeterDate"));
        headerInfos.add(new HeaderInfoDto("IC卡号", false, "miicno"));
        headerInfos.add(new HeaderInfoDto("IC子表号", false, "miljfje"));
        headerInfos.add(new HeaderInfoDto("定额水量", false, "quotaWater"));
        headerInfos.add(new HeaderInfoDto("集中器", false, "concentratorNo"));
        headerInfos.add(new HeaderInfoDto("表位", false, "meterSite"));
        headerInfos.add(new HeaderInfoDto("表井形式", false, "meterBjxs"));
        headerInfos.add(new HeaderInfoDto("不动产单元号", false, "realEstateNo"));
        headerInfos.add(new HeaderInfoDto("子账户银行", false, "bankCode"));
        headerInfos.add(new HeaderInfoDto("子账户编号", false, "bankSubAccount"));
        headerInfos.add(new HeaderInfoDto("行业分类", false, "tradeClassify"));
        headerInfos.add(new HeaderInfoDto("用户特殊类型", false, "userType"));
        headerInfos.add(new HeaderInfoDto("用户编号", false, "userNo"));
        headerInfos.add(new HeaderInfoDto("行政区域", false, "area"));
        headerInfos.add(new HeaderInfoDto("最后抄码", false, "lastReadingNum"));
        headerInfos.add(new HeaderInfoDto("水表绩效类型", false, "meterPerformanceType"));
        headerInfos.add(new HeaderInfoDto("DMA分区", false, "dmaArea"));
        headerInfos.add(new HeaderInfoDto("册本号", false, "bookNo"));
        headerInfos.add(new HeaderInfoDto("抄表周期", false, "meterReadingCycle"));
        headerInfos.add(new HeaderInfoDto("下次抄表月", false, "nextMonthid"));

        // 4. 立户-用户信息：价格信息
        headerInfos.add(new HeaderInfoDto("用水类型", false, "useWaterType"));
        headerInfos.add(new HeaderInfoDto("优惠策略", false, "prefStrategyId"));
        headerInfos.add(new HeaderInfoDto("优惠证件号码", false, "prefCertNo"));
        headerInfos.add(new HeaderInfoDto("优惠策略开始日期", false, "prefBeginDate"));
        headerInfos.add(new HeaderInfoDto("优惠策略结束日期", false, "prefEndDate"));

        return headerInfos;
    }

    @Override
    public boolean isCheckHeader() {
        // TODO Auto-generated method stub
        return true;
    }
}
